import store from '../store/index.js';
import index from '../unit/index.js';
import actions from '../actions';
import constVal from '../unit/const.js';
import musicObj from '../unit/music.js';
import Block from '../unit/block.js';

let {
	want,
	isClear,
	isOver,
	getNextType
} = index;
let {
	speeds,
	blankLine,
	blankMatrix,
	clearPoints,
	eachLines
} = constVal;
let {
	music
} = musicObj;

const getStartMatrix = (startLines) => { // 生成startLines
	const getLine = (min, max) => { // 返回标亮个数在min~max之间一行方块, (包含边界)
		const count = parseInt((((max - min) + 1) * Math.random()) + min, 10);
		const line = [];
		for (let i = 0; i < count; i++) { // 插入高亮
			line.push(1);
		}
		for (let i = 0, len = 10 - count; i < len; i++) { // 在随机位置插入灰色
			const index = parseInt(((line.length + 1) * Math.random()), 10);
			line.splice(index, 0, 0);
		}
		return line;
	};
	let startMatrix = [];

	for (let i = 0; i < startLines; i++) {
		if (i <= 2) { // 0-3
			startMatrix.push(getLine(5, 8));
		} else if (i <= 6) { // 4-6
			startMatrix.push(getLine(4, 9));
		} else { // 7-9
			startMatrix.push(getLine(3, 9));
		}
	}
	for (let i = 0, len = 20 - startLines; i < len; i++) { // 插入上部分的灰色
		startMatrix.unshift(blankLine.slice());
	}
	return startMatrix;
};

const states = {
	// 自动下落setTimeout变量
	fallInterval: null,

	// 游戏开始
	start: () => {
		if (music.start) {
			music.start();
		}
		console.log("start1", "开始游戏")
		const state = store.state;
		states.dispatchPoints(0);
		console.log("1111",state.speedStart)
		store.commit("speedRun", state.speedStart);
		const startLines = state.startLines;
		const startMatrix = getStartMatrix(startLines);
		console.log("start1", "startMatrix", startMatrix)
		store.commit("matrix", startMatrix);
		console.log("start1", "nexttype", state.next)
		store.commit("moveBlock", new Block({
			type: state.next
		}));
		store.commit("next", getNextType());
		states.auto();
	},

	// 自动下落
	auto: (timeout) => {
		const out = (timeout < 0 ? 0 : timeout);
		let state = store.state;
		let cur = state.cur;
		const fall = () => {
			state = store.state;
			cur = state.cur;
			const next = cur.fall();
			// console.log("auto 移动前", next,state.matrix.map((m)=>{
			// 	return m.slice();
			// }))
			if (want(next, state.matrix)) { //可以移动
				// console.log("auto 可以移动")
				store.commit("moveBlock", next.reset === true ? null : new Block(next));
				// store.commit("moveBlock", next.reset === true ? null : next);
				
				states.fallInterval = setTimeout(fall, speeds[state.speedRun - 1]);
			} else {
				// console.log("auto 不能移动")
				let matrix = state.matrix.map((m) => {
					return m.slice();
				});
				const shape = cur && cur.shape;
				const xy = cur && cur.xy;
				shape.forEach((m, k1) => (
					m.forEach((n, k2) => {
						if (n && xy[0] + k1 >= 0) { // 竖坐标可以为负
							let line = matrix[xy[0] + k1];
							line[xy[1] + k2] = 1;
							matrix[xy[0] + k1] = line;
						}
					})));
				states.nextAround(matrix);
			}
		};
		clearTimeout(states.fallInterval);
		states.fallInterval = setTimeout(fall,
			out === undefined ? speeds[state.speedRun - 1] : out);
	},

	// 一个方块结束, 触发下一个
	nextAround: (matrix, stopDownTrigger) => {
		clearTimeout(states.fallInterval);
		store.commit("lock", true);
		store.commit("matrix", matrix);
		if (typeof stopDownTrigger === 'function') {
			stopDownTrigger();
		}

		const addPoints = (store.state.points + 10) +
			((store.state.speedRun - 1) * 2); // 速度越快, 得分越高

		states.dispatchPoints(addPoints);

		if (isClear(matrix)) {
			if (music.clear) {
				music.clear();
			}
			return;
		}
		if (isOver(matrix)) {
			if (music.gameover) {
				music.gameover();
			}
			states.overStart();
			return;
		}
		setTimeout(() => {
			store.commit("lock", false);
			store.commit("moveBlock", new Block({
				type: store.state.next
			}));
			store.commit("next", getNextType());
			states.auto();
		}, 100);
	},

	// 页面焦点变换
	focus: (isFocus) => {
		store.commit("focus", isFocus);
		if (!isFocus) {
			clearTimeout(states.fallInterval);
			return;
		}
		const state = store.state;
		if (state.cur && !state.reset && !state.pause) {
			states.auto();
		}
	},

	// 暂停
	pause: (isPause) => {
		store.commit("pause", isPause);
		if (isPause) {
			clearTimeout(states.fallInterval);
			return;
		}
		states.auto();
	},

	// 消除行
	clearLines: (matrix, lines) => {
		const state = store.state;
		let newMatrix = matrix;
		lines.forEach(n => {
			newMatrix.splice(n, 1); //删掉这一行
			newMatrix.unshift(blankLine.slice()); //开头加入一个空行
		});
		store.commit("matrix", newMatrix);
		// console.log(state.next)
		store.commit("moveBlock", new Block({
			type: state.next
		}));
		store.commit("next", getNextType());
		states.auto();
		store.commit("lock", false);
		const clearLines = state.clearLines + lines.length;
		store.commit("clearLines", clearLines); // 更新消除行,总共消除了多少行

		const addPoints = store.state.points +
			clearPoints[lines.length - 1]; // 一次消除的行越多, 加分越多
		console.log("得分", addPoints)
		states.dispatchPoints(addPoints);

		const speedAdd = Math.floor(clearLines / eachLines); // 消除多少行数, 增加对应速度
		let speedNow = state.speedStart + speedAdd;
		speedNow = speedNow > 6 ? 6 : speedNow;
		store.commit("speedRun", speedNow);

	},

	// 游戏结束, 触发动画
	overStart: () => {
		console.log("restart", "overStart");
		clearTimeout(states.fallInterval);
		store.commit("lock", true);
		store.commit("reset", true);
		store.commit("pause", false);
	},

	// 游戏结束动画完成
	overEnd: () => {
		store.commit("matrix", blankMatrix);
		store.commit("moveBlock", null);
		store.commit("reset", false);
		store.commit("lock", false);
		store.commit("clearLines", 0);
	},

	// 写入分数
	dispatchPoints: (point) => { // 写入分数, 同时判断是否创造最高分
		store.commit("points", point);
		if (point > 0 && point > store.state.max) {
			store.commit("max", point);
		}
	},
};

export default states;
